<!--
 * SelectTable 下拉表格组件
 * @author: Goal
 * @since: 2023-11-13
 * SelectTable.vue
 *
 * 属性(带有[Required]为必填属性)
 * data[Required]: 双向绑定数据
 * fields[Required]: 表格列对象
 * tableData[Required]: 表格数据对象
 * value: 双向绑定数据的值(为空时data属性为表格当前行数据对象)
 * label: 选择框显示的文本内容(为空时分别查看value和objKey是否为空,若value和objKey都有值,则value优先级大于objKey)
 * objKey: 对象key(绑定值的唯一标识，绑定值为对象时必填)
 * placeholder: 选择框占位文本
 * size: 组件大小
 * border: 表格是否带有边框
 * clearable: 下拉框是否可清空
 * curPage: 表格分页当前页
 * pageSize: 表格分页每页总数
 * total: 表格总行数
 * pageLayout: 分页按钮布局(参考elementplus)
 * hideOnSinglePage: 在只有一页时是否隐藏分页
 * editable: 下拉框是否可输入
-->
<template>
	<el-select
		id="select"
		ref="selectTable"
		v-model="selectShowValue"
		:placeholder="props.placeholder"
		:size="props.size"
		:clearable="props.clearable"
		:filterable="editable"
		@clear="clear"
		@blur="blurInput"
		style="width: 100%"
		@input="handleSelectInput"
	>
		<template #empty>
			<div style="padding: 0 10px;text-align: left">
				<el-table
					ref="table"
					:data="props.tableData"
					:highlight-current-row="props.isHighlight"
					size="small"
					:fit="true"
					:border="props.border"
					@row-click="handleRowClick"
					@current-change="handleCurrentChange"
					style="width: 100%"
				>
					<!-- <el-table-column type="selection" width="55" /> -->
					<el-table-column
						v-for="(field, index) in props.fields"
						:prop="field.prop"
						:key="index"
						:label="field.label"
						:width="field.width"
						align="center"
						:show-overflow-tooltip="field.showTooltip"
					/>
				</el-table>
				<div class="paging" v-if="props.curPage && props.pageSize && props.total">
					<el-pagination
						:page-size="props.pageSize || 10"
						:pager-count="5"
						size="small"
						:layout="props.pageLayout"
						:current-page="props.curPage"
						:total="props.total"
						:background="props.pageBackground"
						:hideOnSinglePage="props.hideOnSinglePage"
						@size-change="sizeChange"
						@current-change="currentChange"
					/>
				</div>
			</div>
		</template>
	</el-select>
</template>

<script setup lang="ts">
interface Field {
	prop: string; //与tableData需要显示的值对应
	label: string;
	width: number;
	showTooltip?: boolean;
}

interface Props {
	data: any;
	//表格属性
	fields: Field[];
	tableData: object[];
	isHighlight?: boolean;
	border?: boolean;
	//下拉框属性
	label?: string;
	value?: string;
	objKey?: string;
	placeholder?: string;
	clearable?: boolean;
	editable?: boolean;
	//分页属性
	curPage?: number;
	pageSize?: number;
	total?: number;
	pageBackground?: boolean;
	pageLayout?: string;
	hideOnSinglePage?: boolean;
	//通用属性
	size?: string;
}

const props = withDefaults(defineProps<Props>(), {
	placeholder: 'please select',
	size: 'default',
	isHighlight: true,
	value: undefined,
	label: undefined,
	border: false,
	total: 0,
	// pageBackground: true,
	// pageLayout: "prev, pager, next",
	pageLayout: 'total, sizes, prev, pager, next, jumper',
	hideOnSinglePage: false,
	clearable: false,
	editable: false,
});

interface Emits {
	(e: 'update:data', val: any): void;

	(e: 'sizeChange', val: number): void;

	(e: 'currentChange', val: number): void;

	(e: 'inputChange', val: string): void;

	(e: 'blur', val: FocusEvent): void;

	(e: 'clear', val: any): void;

	(e: 'handleRowClick', val: any): void;
}

const emits = defineEmits<Emits>();

const selectTable = ref();
const table = ref();
const selectShowValue = ref(null);
const rowObj = ref(null);

const data = computed({
	get() {
		return props.data;
	},
	set(val) {
		emits('update:data', val);
	},
});

/*onMounted(() => {
  //处理数据回显
  // debugger;
  if (props.data) {
    // 配置label则显示label
    if (typeof props.label !== "undefined") {
      // 配置了value属性，则找到与value属性值一样的表格行对象，将配置的label回显到下拉框
      if (typeof props.value !== "undefined") {
        let row = props.tableData.find(
          (item) => item[props.value] === props.data
        );
        selectShowValue.value =
          typeof row === "undefined" ? props.data : row[props.label];
        // 配置了objKey属性，则找到与objKey属性值一样的表格行对象，将配置的label回显到下拉框
      } else if (typeof props.objKey !== "undefined") {
        let row = props.tableData.find(
          (item) => item[props.objKey] === props.data[props.objKey]
        );
        selectShowValue.value =
          typeof row === "undefined" ? props.data : row[props.label];
      }
      //没有配置label属性则回显value或者objKey
    } else {
      // 配置了value属性，则找到与value属性值一样的表格行对象，将配置的label回显到下拉框
      if (typeof props.value !== "undefined") {
        let row = props.tableData.find(
          (item) => item[props.value] === props.data
        );
        selectShowValue.value =
          typeof row === "undefined" ? props.data : row[props.value];
        // 配置了objKey属性，则找到与objKey属性值一样的表格行对象，将配置的label回显到下拉框
      } else if (typeof props.objKey !== "undefined") {
        let row = props.tableData.find(
          (item) => item[props.objKey] === props.data
        );
        selectShowValue.value =
          typeof row === "undefined" ? props.data : row[props.objKey];
      }
    }
  }
});*/

watch(data, (newVal) => {
	if (newVal) {
		// 配置label则显示label
		if (typeof props.label !== 'undefined') {
			// 配置了value属性，则找到与value属性值一样的表格行对象，将配置的label回显到下拉框
			if (typeof props.value !== 'undefined') {
				let row = props.tableData.find((item) => item[props.value] === props.data);
				selectShowValue.value = typeof row === 'undefined' ? props.data : row[props.label];
				selectShowValue.value = typeof row === 'undefined' ? props.data : row[props.label];
				// 配置了objKey属性，则找到与objKey属性值一样的表格行对象，将配置的label回显到下拉框
			} else if (typeof props.objKey !== 'undefined') {
				let row = props.tableData.find((item) => item[props.objKey] === props.data[props.objKey]);
				selectShowValue.value = typeof row === 'undefined' ? props.data : row[props.label];
			}
			//没有配置label属性则回显value或者objKey
		} else {
			// 配置了value属性，则找到与value属性值一样的表格行对象，将配置的label回显到下拉框
			if (typeof props.value !== 'undefined') {
				let row = props.tableData.find((item) => item[props.value] === props.data);
				selectShowValue.value = typeof row === 'undefined' ? props.data : row[props.value];
				// 配置了objKey属性，则找到与objKey属性值一样的表格行对象，将配置的label回显到下拉框
			} else if (typeof props.objKey !== 'undefined') {
				let row = props.tableData.find((item) => item[props.objKey] === props.data);
				selectShowValue.value = typeof row === 'undefined' ? props.data : row[props.objKey];
			}
		}
	}
});

watch(
	() => props.tableData,
	(newData) => {
		// 重新计算高亮行
		if (table.value) {
			table.value.setCurrentRow(null); // 清除当前高亮
			const matchedRow = newData.find((row) => {
				if (typeof props.value !== 'undefined') {
					return row[props.value] === props.data;
				} else if (typeof props.objKey !== 'undefined') {
					return row[props.objKey] === props.data[props.objKey];
				} else if (typeof props.label !== 'undefined') {
					return row[props.label] === props.data;
				}
				return false;
			});
			if (matchedRow) {
				table.value.setCurrentRow(matchedRow);
			}
		}
	}
);
//监听下拉框内容变化，主要用于清空选择框内容
watch(selectShowValue, (newVal) => {
	if (newVal === '') {
		emits('update:data', newVal);
		//取消高亮
		table.value.setCurrentRow(null);
	}
});

/**
 * 点击当前行事件
 * @param val
 */
const handleRowClick = (val: any) => {
	if (!val) {
		return;
	}
	rowObj.value = { ...val };
	// 如果没有配置label则显示value或者objKey
	setLabel(val);
	//  设置双向绑定值
	if (typeof props.value !== 'undefined') {
		emits('update:data', val[props.value]);
	} else {
		emits('update:data', val);
	}
	selectTable.value.blur();

	emits('handleRowClick', val);
};

// 当前行改变 放到click中去,因为这里会触发多次(一次是点击,一次是回显的情况)
const handleCurrentChange = (val: number) => {};

/**
 * 下拉框输入值变化
 */
const handleSelectInput = (e) => {
	// emits('inputChange', document.getElementById('select')?.value);
	emits('inputChange', e.target.value);
};

/**
 * 每页大小改变
 * @param val
 */
const sizeChange = (val: number) => {
	emits('sizeChange', val);
};
/**
 * 失去焦点
 * @param e
 */
const blurInput = (e: FocusEvent) => {
	emits('blur', e);
};

/**
 * 清理的时候 重置值
 */
const clear = () => {
	emits('clear');
};
/**
 * 当前页改变
 * @param val
 */
const currentChange = (val: number) => {
	emits('currentChange', val);
};

/**
 * 设置下拉框选择显示文本内容
 * @param val
 */
const setLabel = (val: any) => {
	// 如果没有配置label则显示value或者objKey
	if (typeof props.label === 'undefined') {
		// 如果配置了value,则显示value
		if (typeof props.value !== 'undefined') {
			selectShowValue.value = val[props.value];
		} else if (typeof props.objKey !== 'undefined') {
			//没有配置value但配置了objKey,则显示objKey
			selectShowValue.value = val[props.objKey];
		}
	} else {
		selectShowValue.value = val[props.label];
	}
};
</script>

<style scoped lang="scss">
.paging {
	padding: 0 10px;
}
</style>
